package org.fixies.resource;

import org.fixies.utils.Log;
import org.fixies.utils.UnexpectedProblemException;
import org.fixies.utils.Validator;

import java.util.ArrayList;
import java.util.List;

/**
 * 一度だけ初期化を行なう初期化処理
 *
 * @author Kawasaki
 */
public class InitializeOnce implements Initializer {

    private static boolean init__ = false;

    private List<Initializer> initializers_ = new ArrayList<Initializer>();

    public synchronized void setInitializers(List<Initializer> initializers) {
        Validator.notNull(initializers);
        initializers_ = initializers;
    }

    public synchronized void addInitializers(List<Initializer> initializers) {
        Validator.notNull(initializers);
        initializers_.addAll(initializers);
    }

    private static boolean initialized() {
        return init__;
    }
    private static void initialized(boolean b) {
        init__ = b;
    }

    public synchronized void initialize() {
        if (initialized()) {
            return;
        }
        for (Initializer each : initializers_) {
            try {
                each.initialize();
            } catch (Exception e) {
                throw new UnexpectedProblemException(e, "An exception occured in initialization.");
            }
        }
        addShutdownHook();
        initialized(true);
    }

    public synchronized void terminate() {
        for (Initializer e : initializers_) {
            try {
                e.terminate();
            } catch (Exception ignored) {
                Log.warn("An exception occured in termination.", ignored);
            }
        }
        initialized(false);
    }

    private void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                terminate();
            }
        });
    }
}
